// 为项目添加Service层和完善的事务管理

@Service
@Transactional  // 类级别事务配置
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    /**
     * 用户注册 - 需要写事务
     */
    @Transactional(rollbackFor = Exception.class)
    public User registerUser(SignupRequest signupRequest) {
        // 1. 验证用户名唯一性
        if (userRepository.existsByUsername(signupRequest.getUsername())) {
            throw new UserAlreadyExistsException("用户名已被使用");
        }
        
        // 2. 验证邮箱唯一性
        if (userRepository.existsByEmail(signupRequest.getEmail())) {
            throw new EmailAlreadyExistsException("邮箱已被使用");
        }
        
        // 3. 创建用户
        User user = new User(
            signupRequest.getUsername(),
            signupRequest.getEmail(),
            passwordEncoder.encode(signupRequest.getPassword())
        );
        
        // 4. 保存用户
        User savedUser = userRepository.save(user);
        
        // 5. 记录用户注册日志（如果失败，整个事务回滚）
        logUserRegistration(savedUser);
        
        // 6. 发送欢迎邮件（如果失败，整个事务回滚）
        sendWelcomeEmail(savedUser);
        
        return savedUser;
    }
    
    /**
     * 查询用户 - 只读事务
     */
    @Transactional(readOnly = true)
    public Optional<User> findByUsername(String username) {
        return userRepository.findByUsername(username);
    }
    
    /**
     * 批量创建用户 - 复杂事务场景
     */
    @Transactional(rollbackFor = Exception.class)
    public List<User> batchCreateUsers(List<SignupRequest> requests) {
        List<User> createdUsers = new ArrayList<>();
        
        for (SignupRequest request : requests) {
            // 如果任何一个用户创建失败，整个批次都会回滚
            User user = registerUser(request);
            createdUsers.add(user);
        }
        
        return createdUsers;
    }
    
    /**
     * 更新用户密码 - 需要事务保证一致性
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(Long userId, String oldPassword, String newPassword) {
        // 1. 查找用户
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new UserNotFoundException("用户不存在"));
        
        // 2. 验证旧密码
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new InvalidPasswordException("旧密码不正确");
        }
        
        // 3. 更新密码
        user.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(user);
        
        // 4. 记录密码修改日志
        logPasswordChange(user);
        
        // 5. 发送安全通知邮件
        sendSecurityNotification(user);
    }
    
    /**
     * 删除用户 - 级联删除相关数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long userId) {
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new UserNotFoundException("用户不存在"));
        
        // 1. 删除用户相关的所有数据
        deleteUserProfiles(userId);
        deleteUserSessions(userId);
        deleteUserLogs(userId);
        
        // 2. 最后删除用户
        userRepository.delete(user);
        
        // 如果任何步骤失败，整个删除操作都会回滚
    }
    
    // 私有方法，继承类级别的事务
    private void logUserRegistration(User user) {
        // 记录注册日志
    }
    
    private void sendWelcomeEmail(User user) {
        // 发送欢迎邮件
    }
    
    private void logPasswordChange(User user) {
        // 记录密码修改日志
    }
    
    private void sendSecurityNotification(User user) {
        // 发送安全通知
    }
    
    private void deleteUserProfiles(Long userId) {
        // 删除用户资料
    }
    
    private void deleteUserSessions(Long userId) {
        // 删除用户会话
    }
    
    private void deleteUserLogs(Long userId) {
        // 删除用户日志
    }
}

/**
 * 事务传播示例
 */
@Service
public class UserAuditService {
    
    @Autowired
    private UserService userService;
    
    /**
     * 需要新事务的场景 - 审计日志
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void auditUserAction(String username, String action) {
        // 即使主事务回滚，审计日志也要保存
        // 这里会创建新的事务
        AuditLog log = new AuditLog(username, action, new Date());
        auditLogRepository.save(log);
    }
    
    /**
     * 支持当前事务的场景
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public void optionalAudit(String username, String action) {
        // 如果有事务就加入，没有就以非事务方式执行
        // 适用于可选的操作
    }
}

/**
 * 编程式事务示例
 */
@Service
public class UserTransactionService {
    
    @Autowired
    private PlatformTransactionManager transactionManager;
    
    @Autowired
    private UserRepository userRepository;
    
    /**
     * 编程式事务 - 更精细的控制
     */
    public void complexUserOperation(SignupRequest request) {
        TransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        
        try {
            // 1. 第一阶段操作
            User user = new User(request.getUsername(), request.getEmail(), 
                               passwordEncoder.encode(request.getPassword()));
            userRepository.save(user);
            
            // 2. 检查点 - 可以选择性提交
            if (shouldContinue()) {
                // 3. 第二阶段操作
                sendWelcomeEmail(user);
                logUserRegistration(user);
                
                // 4. 提交事务
                transactionManager.commit(status);
            } else {
                // 回滚事务
                transactionManager.rollback(status);
            }
            
        } catch (Exception e) {
            // 异常时回滚
            transactionManager.rollback(status);
            throw e;
        }
    }
    
    private boolean shouldContinue() {
        // 业务逻辑判断
        return true;
    }
}

/**
 * 事务监听器示例
 */
@Component
public class UserTransactionEventListener {
    
    /**
     * 事务提交后执行
     */
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleUserRegistered(UserRegisteredEvent event) {
        // 事务成功提交后发送邮件
        emailService.sendWelcomeEmail(event.getUser());
    }
    
    /**
     * 事务回滚后执行
     */
    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void handleUserRegistrationFailed(UserRegisteredEvent event) {
        // 事务回滚后记录失败日志
        logger.error("用户注册失败: {}", event.getUser().getUsername());
    }
}

/**
 * 重构后的Controller - 使用Service层
 */
@RestController
@RequestMapping("/api/auth")
public class AuthController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private AuthService authService;
    
    @PostMapping("/signup")
    public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
        try {
            // 委托给Service层处理，Service层管理事务
            User user = userService.registerUser(signUpRequest);
            return ResponseEntity.ok(new MessageResponse("用户注册成功!"));
        } catch (UserAlreadyExistsException | EmailAlreadyExistsException e) {
            return ResponseEntity.badRequest()
                .body(new MessageResponse("注册失败: " + e.getMessage()));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new MessageResponse("系统错误，请稍后重试"));
        }
    }
}

/**
 * 自定义异常类
 */
public class UserAlreadyExistsException extends RuntimeException {
    public UserAlreadyExistsException(String message) {
        super(message);
    }
}

public class EmailAlreadyExistsException extends RuntimeException {
    public EmailAlreadyExistsException(String message) {
        super(message);
    }
}

public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

public class InvalidPasswordException extends RuntimeException {
    public InvalidPasswordException(String message) {
        super(message);
    }
}